package com.lincoln.cloud.servercenter.bean;

import com.lincoln.cloud.servercenter.abstracter.IntServerPool;
import com.lincoln.cloud.servercenter.abstracter.MapServerPoolContainer;
import com.lincoln.cloud.servercenter.abstracter.NettyCommunicationProtocol;
import com.lincoln.cloud.servercenter.annotation.ServerCenter;
import com.lincoln.cloud.servercenter.interfaces.CommunicationProtocol;
import com.lincoln.cloud.servercenter.interfaces.ServerPool;
import com.lincoln.cloud.servercenter.interfaces.ServerPoolContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 服务注册中心启动上下文(不能写私有方法或成员),本类应该只负责启动服务时各种配置
 *
 * @author lincoln
 */
public class ServerCenterContext {
    private static final Logger logger = LoggerFactory.getLogger(ServerCenterContext.class);

    /**
     * 服务注册中心相关配置(代码层面)
     */
    private static ServerCenterBean serverCenterBean = new ServerCenterBean();
    /**
     * 通信协议
     */
    private static CommunicationProtocol communicationProtocol;

    public static void run(Class main) throws Exception {
        if (main.getAnnotation(ServerCenter.class) == null) {
            init();
        } else {
            ServerCenter serverCenter = (ServerCenter) main.getAnnotation(ServerCenter.class);
            if (serverCenter.scannerPath() != null && !"".equals(serverCenter.scannerPath())) {
                serverCenterBean().setScannerPath(new String[]{serverCenter.scannerPath()});
            }
            if (serverCenter.scannerPaths() != null && serverCenter.scannerPaths().length > 0) {
                serverCenterBean().setScannerPath(serverCenter.scannerPaths());
            }
            if (serverCenter.serverPool() != null) {
                serverPool(serverCenter.serverPool().newInstance());
            }
            if (serverCenter.communicationProtocol() != null) {
                communicationProtocol(serverCenter.communicationProtocol().newInstance());
            }
            init();
        }
    }

    /**
     * 初始化
     *
     * @return
     */
    public static boolean init() throws Exception {
        if (communicationProtocol() == null) {
            communicationProtocol(new NettyCommunicationProtocol());
        }
        communicationProtocol.init();
        //检查服务器池有没有初始化
        if (serverPool() == null) {
            serverPool(new IntServerPool());
        }
        //检查服务器池的容器有没有初始化
        if (serverPoolContainer() == null) {
            serverPoolContainer(new MapServerPoolContainer());
        }
        logger.info("服务注册中心启动成功");
        return true;
    }

    /**
     * 返回serverCenterBean
     *
     * @return
     */
    public static ServerCenterBean serverCenterBean() {
        return serverCenterBean;
    }

    /**
     * 设置服务器池
     *
     * @param serverPool
     * @return
     */
    public static ServerCenterContext serverPool(ServerPool serverPool) {
        serverCenterBean.setServerPool(serverPool);
        return new ServerCenterContext();
    }

    /**
     * 返回服务器池
     *
     * @return
     */
    public static ServerPool serverPool() {
        return serverCenterBean.getServerPool();
    }

    /**
     * 设置服务器池的容器
     *
     * @param serverPoolContainer
     * @return
     * @throws Exception
     */
    public static ServerCenterContext serverPoolContainer(ServerPoolContainer serverPoolContainer) throws Exception {
        if (serverPool() == null) {
            throw new Exception("服务器池没有初始化");
        }
        serverCenterBean.getServerPool().setContainer(serverPoolContainer);
        return new ServerCenterContext();
    }

    /**
     * 返回服务器池的容器
     *
     * @return
     */
    public static ServerPoolContainer serverPoolContainer() throws Exception {
        if (serverPool() == null) {
            throw new Exception("服务器池没有初始化");
        }
        return serverCenterBean.getServerPool().getContainer();
    }

    /**
     * 返回通信协议
     *
     * @return
     */
    public static CommunicationProtocol communicationProtocol() {
        return communicationProtocol;
    }

    /**
     * 设置通信协议
     *
     * @param communicationProtocol
     */
    public static void communicationProtocol(CommunicationProtocol communicationProtocol) {
        ServerCenterContext.communicationProtocol = communicationProtocol;
    }
}
